<?php
include_once 'library/Controller/IController.php';
class BaseController implements IController{
	const ACTION_SUFFIX = "Action";

	/**
	 * Enter description here ...
	 * @var array
	 */
	private $_route;
	/**
	 * HttpContext  here ...
	 * @var HttpContext
	 */
	private $_context;
	private $_module;
	private $_controller;
	private $_action;
	private $_view;
	private $_viewType;

	private $_layout;
	private $_layoutName;
	private $_viewPath;

	private $_hasView;
	private $_hasLayout;
	/**
	 * LayoutConfig.
	 * @var LayoutConfig
	 */
	private $_layoutConfig;
	protected $viewTitle;
	/**
	 * ViewRender
	 * @var ViewRender
	 */
	protected $_viewRender;
	
	/**
	 * Controller's Model.
	 * @var BaseModel
	 */
	protected $_model;
	/**
	 * Table Name in DB.
	 * @var String
	 */
	protected $_tableName;
	/**
	 * Enter description here ...
	 * @param ControllerRoute $route
	 */
	public function __construct(){
		$this->_hasView = true;
		$this->_hasLayout = true;
		$this->_init();
		$this->_auth();
	}

	protected function _init(){
		
	}
	public function _auth(){
		
	}
	public function run(){
		$this->_layoutConfig = LayoutConfig::getInstance($this->_layoutName);
		$function = $this->_action . BaseController::ACTION_SUFFIX;
		if(!method_exists(get_class($this), $function)){
			Log::error(get_class($this), $function ." not Found");
			$function = Configuration::ACTION_DEFAULT . BaseController::ACTION_SUFFIX;
		}
		//TO DO pre plugin
		$this->_preRun();
		$this->_viewRender = new ViewRender($this->_context,$this->_module, $this->_controller, $this->_action, $this->_view, $this->_viewType, $this->_module);
		$this->{$function}();
		//TO DO post plugin
		$this->_postRun();
		$this->_preView();
		$this->_viewRender->render();
		$this->_postView();
	}

	public function _preRun(){}
	public function _postRun(){}
	public function _preView(){}
	public function _postView(){}

	/**
	 * Set MVC parram for controller.
	 * @param array $route
	 * @param HttpContext $context
	 */
	public function setParram($route,$context){
		$this->_route = $route;
		$this->_module = $route[Configuration::MODULE];
		$this->_controller = $route[Configuration::CONTROLLER];
		$this->_action = isset($route[Configuration::ACTION]) ? $route[Configuration::ACTION]: Configuration::ACTION_DEFAULT;
		$this->_view = isset($route[Configuration::VIEW]) ? $route[Configuration::VIEW]: Configuration::VIEW_DEFAULT;
		$this->_viewType = isset($route[Configuration::VIEW_TYPE]) ? $route[Configuration::VIEW_TYPE]: Configuration::VIEW_TYPE_DEFAULT;
		$this->_layoutName = $this->_module;
		$this->_context = $context;
		$this->initModel();
	}
	/**
	 * Initialize Controller's Model.
	 */
	public function initModel(){
		$this->_tableName = $this->_controller;;
		$this->_model = ModelFactory::minstance($this->_tableName, $this->_module);
		$this->initEntity();
	}
	/**
	 * Set Enity for Controller's Model.
	 */
	public function initEntity(){
		$this->_model->setEntity(EntityFactory::instance($this->_tableName));
	}
	public function getRoute(){
		return $this->_route;
	}
	public function getRouteParram($key, $default = null){
		if(isset($this->_route[$key])) return $this->_route[$key];
		return $default;
	}
	/**
	 * return HttpContext.
	 * @return HttpContext
	 */
	public function getContext(){
		return $this->_context;
	}
	public function getModule(){
		return $this->_module;
	}
	public function setModule($module){
		$this->_module = $module;
	}
	public function getController(){
		return $this->_controller;
	}
	public function setController($controller){
		$this->_controller = $controller;
	}
	public function getAction(){
		return $this->_action;
	}
	public function setAction($action){
		$this->_action = $action;
	}
	public function getView(){
		return $this->_view;
	}
	public function setView($view){
		$this->_view = $view;
	}
	public function getViewType(){
		return $this->_viewType;
	}
	public function setViewType($viewType){
		$this->_viewType = $viewType;
	}
	/**
	 * ViewRender.
	 * @return ViewRender
	 */
	public function getViewRender(){
		return $this->_viewRender;
	}
	/**
	 * ViewRender.
	 * @return ViewRender
	 */
	public function view(){
		return $this->_viewRender;
	}
	public function validateData($entity){
		return array('isError'=>false,'entity'=>$entity,'errors'=>null);
	}
	public function getControllerName(){
		return str_replace(ControllerFactory::_SUFFIX, "", get_class($this));
	}
	public function setTableName($tableName){
		$this->_tableName = $tableName;
	}
	public function getTableName(){
		return $this->_tableName;
	}
	/**
	 * Redirect to page.
	 * @param String $url
	 * @param int $num
	 */
	function _redirect($url, $internal = true, $num = null){
		static $http = array (
		100 => "HTTP/1.1 100 Continue",
		101 => "HTTP/1.1 101 Switching Protocols",
		200 => "HTTP/1.1 200 OK",
		201 => "HTTP/1.1 201 Created",
		202 => "HTTP/1.1 202 Accepted",
		203 => "HTTP/1.1 203 Non-Authoritative Information",
		204 => "HTTP/1.1 204 No Content",
		205 => "HTTP/1.1 205 Reset Content",
		206 => "HTTP/1.1 206 Partial Content",
		300 => "HTTP/1.1 300 Multiple Choices",
		301 => "HTTP/1.1 301 Moved Permanently",
		302 => "HTTP/1.1 302 Found",
		303 => "HTTP/1.1 303 See Other",
		304 => "HTTP/1.1 304 Not Modified",
		305 => "HTTP/1.1 305 Use Proxy",
		307 => "HTTP/1.1 307 Temporary Redirect",
		400 => "HTTP/1.1 400 Bad Request",
		401 => "HTTP/1.1 401 Unauthorized",
		402 => "HTTP/1.1 402 Payment Required",
		403 => "HTTP/1.1 403 Forbidden",
		404 => "HTTP/1.1 404 Not Found",
		405 => "HTTP/1.1 405 Method Not Allowed",
		406 => "HTTP/1.1 406 Not Acceptable",
		407 => "HTTP/1.1 407 Proxy Authentication Required",
		408 => "HTTP/1.1 408 Request Time-out",
		409 => "HTTP/1.1 409 Conflict",
		410 => "HTTP/1.1 410 Gone",
		411 => "HTTP/1.1 411 Length Required",
		412 => "HTTP/1.1 412 Precondition Failed",
		413 => "HTTP/1.1 413 Request Entity Too Large",
		414 => "HTTP/1.1 414 Request-URI Too Large",
		415 => "HTTP/1.1 415 Unsupported Media Type",
		416 => "HTTP/1.1 416 Requested range not satisfiable",
		417 => "HTTP/1.1 417 Expectation Failed",
		500 => "HTTP/1.1 500 Internal Server Error",
		501 => "HTTP/1.1 501 Not Implemented",
		502 => "HTTP/1.1 502 Bad Gateway",
		503 => "HTTP/1.1 503 Service Unavailable",
		504 => "HTTP/1.1 504 Gateway Time-out"
		);
		if($num != null){
			header($http[$num]);
		}
		if($internal && $this->_model != Configuration::MODULE_DEFAULT){
			$url = $this->_context->getBaseUrl().$this->_module.SLASH.$url;
		}
		header ("Location: ".$url);
	}
}